home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1995 October / EnigmA AMIGA RUN 01 (1995)(G.R. Edizioni)(IT)[!][issue 1995-10][Aminet 7].iso / Aminet / gfx / show / amipeg04.lha / aMiPEG_0.4 / ham8.c < prev    next >
C/C++ Source or Header  |  1994-04-22  |  9KB  |  371 lines

  1. /*
  2.  *  This source copes with all amiga-specific stuff as opening the screen, resizing
  3.  *  it using user copper lists, etc.
  4.  *
  5.  *  Copper-based resizing is now implemented, although no aspect ratio is taken care of.
  6.  *
  7.  *  HAM6 is supported now.
  8.  *
  9.  *  Michael Rausch  14-4-94  1:11:59
  10.  */
  11.  
  12. #include <proto/exec.h>
  13. #include <proto/intuition.h>
  14. #include <proto/graphics.h>
  15.  
  16. #include <exec/memory.h>
  17. #include <hardware/custom.h>
  18. #include <graphics/copper.h>
  19. #include <graphics/gfxbase.h>
  20. #include <graphics/gfxmacros.h>
  21. #include <graphics/videocontrol.h>
  22. #include <graphics/displayinfo.h>
  23. #include <graphics/display.h>
  24.  
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28.  
  29. #include "video.h"
  30. #include "proto.h"
  31. extern int ditherType;
  32.  
  33. extern void HAM8_Init(struct RastPort *);    // kinda static
  34. extern void HAM8_Init_lores(struct RastPort *);
  35. extern void HAM6_Init_lores(struct RastPort *);
  36.  
  37. void (*HAM8_draw)(void *, int, int);
  38.  
  39.  
  40. #define custom ((*(volatile struct Custom *)(0xdff000)))
  41.  
  42.  
  43. struct IntuitionBase *IntuitionBase;
  44. struct GfxBase *GfxBase;
  45. extern struct ExecBase *SysBase;
  46. static struct Screen *screen;
  47. static ULONG soerror = NULL;
  48.  
  49. int gfxver;
  50. ULONG *kaiko = NULL;
  51.  
  52. int lores=TRUE, sdbl=TRUE, ham6=FALSE;
  53.  
  54. int max_x, max_y;
  55.  
  56. static struct ColorSpec firstblack[2]={ {0,0,0,0}, {-1, 0,0,0} };    /* Color 0 is 0x000*/
  57.  
  58.  
  59. static void Quit(char *why, int failcode)
  60. {
  61.     puts(why);
  62.     exit(failcode);
  63. }
  64.  
  65. static void output_term(void)
  66. {
  67.     if (screen)
  68.     {
  69.         FreeVPortCopLists(&(screen->ViewPort));
  70.         RemakeDisplay();
  71.         CloseScreen(screen);
  72.     }
  73.     if (IntuitionBase) CloseLibrary((struct Library *) IntuitionBase);
  74.     if (GfxBase) CloseLibrary((struct Library *) GfxBase);
  75. }
  76.  
  77.  
  78. void InitColorDisplay(char *name)
  79. {
  80.     atexit(output_term);
  81.  
  82.     if ((GfxBase=(struct GfxBase *) OpenLibrary("graphics.library",37))==NULL)
  83.         Quit("graphics.library is too old, <V39",25);
  84.     if ((IntuitionBase=(struct IntuitionBase *) OpenLibrary("intuition.library",37))==NULL)
  85.         Quit("intuition.library is too old, <V39",25);
  86.  
  87.     gfxver = GfxBase->LibNode.lib_Version;
  88.     if(gfxver>=40) kaiko = GfxBase->ChunkyToPlanarPtr;
  89.  
  90.     HAM8_draw = (void (*)(void *, int, int)) NoDitherImage;    // method casting ... argh!
  91.     DoDitherImage = NoDitherImage;
  92. }
  93.  
  94.  
  95. /*
  96.  *   Resize the display using a copper list. Nifty'n neat amiga feature.
  97.  *
  98.  *   Phew ... takes now 2 hours to fiddle the system-compliant custom modulo stuff.
  99.  */
  100. void ResizeDisplay(int w, int h)
  101. {
  102.     struct UCopList *ucoplist;
  103.     static struct TagItem uCopTags[] = {
  104.         { VC_NoColorPaletteLoad, TRUE },
  105.         { VTAG_USERCLIP_SET, NULL },
  106.         { VTAG_END_CM, NULL }};
  107.     int i,j,k, y, fp_each, locallores;
  108.     struct CopList *dspins;
  109.     struct CopIns *copins;
  110.     short bpl1mod=-1, bpl2mod=-1, last1, last2, this1, this2;
  111.     ULONG id;
  112.     struct DimensionInfo dim_info;
  113.     char pubscreenname[MAXPUBSCREENNAME];
  114.     struct Screen *pubscreen;
  115.  
  116.     if (ditherType == NO_DITHER) return;
  117.  
  118.     GetDefaultPubScreen(pubscreenname);
  119.     pubscreen = LockPubScreen(pubscreenname);
  120.     id = GetVPModeID(&(pubscreen->ViewPort)) & MONITOR_ID_MASK;
  121.     UnlockPubScreen(NULL, pubscreen);
  122.  
  123.     if (GetDisplayInfoData(FindDisplayInfo(id), (UBYTE *)&dim_info, sizeof(struct DimensionInfo), DTAG_DIMS, 0))
  124.         max_y=dim_info.StdOScan.MaxY - dim_info.StdOScan.MinY + 1;
  125.     else
  126.         max_y=200;
  127.  
  128.     if(h>max_y)
  129.         sdbl=FALSE, max_y<<=1;
  130.  
  131.     if(!(GfxBase->ChipRevBits0 & (GFXF_AA_ALICE|GFXF_AA_LISA)))
  132.         ham6 = TRUE;
  133.  
  134.     if(ham6)
  135.         lores=TRUE;
  136.     locallores = lores && (w<=160);
  137.     max_x = (locallores ? 320 : 640);
  138.  
  139.     switch(id)
  140.     {
  141.         case A2024_MONITOR_ID:
  142.             Quit("Get some colors, dude.", 25);
  143.  
  144.         case DBLPAL_MONITOR_ID: /* ARGH!  Kick their butts for this one! */
  145.             if(sdbl)
  146.                 id = locallores ? DBLPALLORESHAMFF_KEY : DBLPALHIRESHAMFF_KEY;
  147.             else
  148.                 id = locallores ? DBLPALLORESHAM_KEY : DBLPALHIRESHAM_KEY;
  149.             break;
  150.  
  151.         case DBLNTSC_MONITOR_ID:
  152.             if(sdbl)
  153.                 id = locallores ? DBLNTSCLORESHAMFF_KEY : DBLNTSCHIRESHAMFF_KEY;
  154.             else
  155.                 id = locallores ? DBLNTSCLORESHAM_KEY : DBLNTSCHIRESHAM_KEY;
  156.             break;
  157.  
  158.         case EURO72_MONITOR_ID:
  159.             if(sdbl)
  160.                 id = locallores ? EURO72LORESHAMDBL_KEY : EURO72PRODUCTHAMDBL_KEY;
  161.             else
  162.                 id = locallores ? EURO72LORESHAM_KEY : EURO72PRODUCTHAM_KEY;
  163.             break;
  164.  
  165.         case VGA_MONITOR_ID:
  166.             if(sdbl)
  167.                 id = locallores ? VGALORESHAMDBL_KEY : VGAPRODUCTHAMDBL_KEY;
  168.             else
  169.                 id = locallores ? VGALORESHAM_KEY : VGAPRODUCTHAM_KEY;
  170.             break;
  171.  
  172.         case DEFAULT_MONITOR_ID:
  173.         case PAL_MONITOR_ID:
  174.         case NTSC_MONITOR_ID:
  175.             if(gfxver >= 40 && sdbl)
  176.                 id = locallores ? LORESHAMSDBL_KEY: HIRESHAMSDBL_KEY;
  177.             else
  178.                 sdbl=FALSE, id = locallores ? HAM_KEY : HIRESHAM_KEY;
  179.             break;
  180.  
  181.         default:
  182.             printf("ModeID is %x\n", id);
  183.             Quit("*shrug*  strange monitor.", 10);
  184.     }
  185.  
  186.     if(!(screen=OpenScreenTags(NULL,
  187.         SA_DisplayID,    id,
  188.         SA_Depth,    ham6?6:8,
  189.         SA_Width,    max_x,
  190.         SA_Colors,    firstblack,
  191.         SA_Type,    CUSTOMSCREEN|SCREENQUIET,
  192.         SA_Quiet,     TRUE,
  193.         SA_Interleaved,    !ham6, //TRUE,
  194.         SA_Overscan,    OSCAN_STANDARD,
  195.         SA_MinimizeISG,    TRUE,
  196.         SA_ErrorCode,    &soerror,
  197.         TAG_END))) Quit("Couldn't open screen.",25);
  198.  
  199.     if((screen->RastPort.BitMap->Depth == 6) && !ham6)
  200.         Quit("Incorrect depth. Please try to specify \"-dither ham6\" explicitely.",25);
  201.  
  202.     if(lores) {
  203.         if(ham6)
  204.         {    // the new ham6 routines do not handle interleaved bitmaps anymore
  205.             HAM6_Init_lores(&(screen->RastPort));
  206.             HAM8_draw = HAM6_draw_lores;
  207.             DoDitherImage = ColorDitherImage_12bit;
  208.         } else {
  209.             HAM8_Init_lores(&(screen->RastPort));
  210.             HAM8_draw = HAM8_draw_lores;
  211.             DoDitherImage = ColorDitherImage_lores;    // lacks kaiko support, actually
  212.         }
  213.         max_x >>=1;
  214.  
  215.     } else {
  216.         HAM8_Init(&(screen->RastPort));
  217.         HAM8_draw = HAM8_draw_hires;
  218.         DoDitherImage = ColorDitherImage;    // kaiko on one day
  219.         max_x >>=2;
  220.     }
  221.  
  222.     if(noDisplayFlag)
  223.         HAM8_draw = (void (*)(void *, int, int)) NoDitherImage;    // method casting ... argh!
  224.  
  225.  
  226.     /* the memory is freed upon exit in output_term via FreeVPortCopLists */
  227.     if(!(ucoplist = AllocMem(sizeof(struct UCopList), MEMF_PUBLIC|MEMF_CLEAR)))
  228.         Quit("No memory for copper list.",25);
  229.  
  230.     /* fiddle out some hardware values from this screen's init copper list */
  231.     dspins=screen->ViewPort.DspIns;
  232.     copins=dspins->CopIns;
  233.     for(i=dspins->Count-1; i>=0; i--, copins++)
  234.     {
  235.         j = copins->DESTDATA;
  236.  
  237.         switch(copins->DESTADDR & 0xfff)    // argh! kick 2.1 messes this up!
  238.         {        
  239.             case (int)&((*(struct Custom *)(0)).bpl1mod):
  240.                 last1=bpl1mod = j;
  241.                 break;
  242.             case (int)&((*(struct Custom *)(0)).bpl2mod):
  243.                 last2=bpl2mod = j;
  244.                 break;
  245.         }
  246.     }
  247.  
  248.     if(bpl1mod==-1 || bpl2mod==-1)
  249.     {
  250.         printf("ooops\n");
  251.         return;    /* hmmm? */
  252.     }
  253.  
  254.     if((bpl1mod == bpl2mod) && sdbl) sdbl=FALSE;
  255.  
  256.     y = screen->Height;
  257.     (void) CINIT(ucoplist, y*3);        /* ... instructions per line */
  258.  
  259.  
  260.     if(sdbl)
  261.     {
  262.         /*
  263.          *  We abuse some of AGA's features here; double-scanning is implemented
  264.          *  by applying bpl1mod to ALL planes on one line, bpl2mod on the next.
  265.          *  Obviously, double-scanning enables some kind of internal chipmem cache.
  266.          *  At least, it's faster. And (because of?) less copper instructions.
  267.          */
  268.  
  269.         fp_each = ((y*2)<<8) / (short)h;
  270.         for(k=fp_each, j=0; j<y; j++)                /* for each line in the display */
  271.         {
  272.  
  273.             if((k-=0x100)>=0x100)                /* we still gotta double the line */
  274.                 this1=bpl1mod;
  275.             else                        /* finally, we are ready; next one */
  276.                 this1=bpl2mod, k=(k&0xff)+fp_each;
  277.  
  278.             if((k-=0x100)>=0x100)                /* we still gotta double the line */
  279.                 this2=bpl1mod;
  280.             else                        /* finally, we are ready; next one */
  281.                 this2=bpl2mod, k=(k&0xff)+fp_each;
  282.  
  283.             if(last1!=this1 || last2!=this2)
  284.                 CWAIT(ucoplist, j, 0);
  285.  
  286.             if(last1!=this1)
  287.             {
  288.                 CMOVE(ucoplist, custom.bpl1mod, this1);
  289.                 last1=this1;
  290.             }
  291.  
  292.             if(last2!=this2)
  293.             {
  294.                 CMOVE(ucoplist, custom.bpl2mod, this2);
  295.                 last2=this2;
  296.             }
  297.         }
  298.     } else {
  299.         /*
  300.          *  No scan-doubling possible; most probably because of a pal/ntsc screen 
  301.          *  and no V40 graphics library available.
  302.          */
  303.  
  304.         bpl1mod -= screen->RastPort.BitMap->BytesPerRow;
  305.  
  306.         fp_each = (y<<8) / (short)h;
  307.         for(k=fp_each, j=0; j<y; j++)                /* for each line in the display */
  308.         {
  309.  
  310.             if((k-=0x100)>=0x100)                /* we still gotta double the line */
  311.                 this1=bpl1mod;
  312.             else                        /* finally, we are ready; next one */
  313.                 this1=bpl2mod, k=(k&0xff)+fp_each;
  314.  
  315.             if(last1!=this1)
  316.             {
  317.                 CWAIT(ucoplist, j, 0);
  318.                 CMOVE(ucoplist, custom.bpl1mod, this1);
  319.                 CMOVE(ucoplist, custom.bpl2mod, this1);
  320.                 last1=this1;
  321.             }
  322.         }
  323.     }
  324.  
  325.     /*
  326.      *  Pretty nifty, isn't it? Finally, even a little bit copper-list-optimizing is build in!
  327.      */
  328.  
  329.     CEND(ucoplist);
  330.  
  331.     /* Set the freshly created user copper list */
  332.     //Forbid();
  333.     screen->ViewPort.UCopIns = ucoplist;
  334.     //Permit();
  335.  
  336.     /*  Enable user copper list clipping for this ViewPort.  */
  337.     (void) VideoControl( screen->ViewPort.ColorMap, uCopTags );
  338.  
  339.     RethinkDisplay();
  340. }
  341.  
  342.  
  343.  
  344. /*
  345.  *--------------------------------------------------------------
  346.  *
  347.  * InitGrayDisplay --
  348.  *
  349.  *    Initialized display for gray scale dither.
  350.  *
  351.  * Results:
  352.  *      None.
  353.  *
  354.  * Side effects:
  355.  *      None.
  356.  *
  357.  *--------------------------------------------------------------
  358.  */
  359.  
  360. #define NUM_COLORS 128
  361.  
  362. void InitGrayDisplay(char *name)
  363. {
  364.     Quit("Not implemented, yet.\n", 0);
  365.  
  366.     DoDitherImage = GrayDitherImage;
  367. }
  368.  
  369.  
  370.  
  371.